from collections import namedtuple
import math
import random

# 空元组

"""
empty_tuple = ("Alice", 20, 98.5)


student_tuple_list = [
    ("Alice", 20, 98.5),
    ("susan", 39, 88.5),
    ("linda", 18, 70.5),
    ("bob", 20, 30.5),
]


def print_stu_info(stu):
    if isinstance(stu, list):
        for item in stu:
            name, age, score = item  # ("Alice", 20, 98.5) 元组的解包
            print(f"姓名：{name},年龄：{age},分数：{score}")


print_stu_info(student_tuple_list)

# 从列表创建元组
list_data = ["Alice", 39, 88, 99, 100]
person_info_tuple = tuple(list_data)

print(person_info_tuple)

name, age, chinese, math, english = person_info_tuple
print(name, age, chinese, math, english)

name_person, *others = person_info_tuple
print(f"利用*进行解包,name_person={name_person},others={others}")


# 从字符串常见元组

tuple_from_string = tuple("1234")
print(tuple_from_string)


fruits = ("apple", "banana", "orange", "grape")

print(fruits[0])  # "apple" - 第一个元素
print(fruits[1])  # "banana" - 第二个元素
print(fruits[-1])  # "grape" - 最后一个元素
print(fruits[-2])  # "orange" - 倒数第二个元素

nums_tuple = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(f"nums_tuple==={nums_tuple},id={id(nums_tuple)}")
print(f"nums_tuple[1::2]={nums_tuple[1::2]},id={id(nums_tuple[1::2])}")


odd_tuple = [item for item in nums_tuple if item % 2 == 0]
print(f"odd_tuple==={odd_tuple},type(odd_tuple)={type(odd_tuple)},id={id(odd_tuple)}")

"""


# 连接元组
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
combined = tuple1 + tuple2
print(combined)  # (1, 2, 3, 4, 5, 6)


# 重复元组
repeat_tuple = tuple1 * 2  #  类似js中的repeat函数
print(f"repeat_tuple={repeat_tuple}")

# 检查元素是否在元组内
names = ("alice", "linda", "susan")
print("alice" in names)

# 获取元组的长度
tuple_len_of_names = len(names)
print(f"names的长度为={tuple_len_of_names}")


# 元组常用方法

numbers = (1, 2, 3, 2, 4, 2, 5, 4, 8, 9)

print(numbers.count(2))  # 3，数字2在元组中出现了3次
print(numbers.index(4))  # 4，数字4第一次出现的位置索引是4
print(numbers.index(2))  # 1，第一个2的索引是1
print(numbers.index(2, 2))  # 3，从索引2起，第一个2的位置是3


# 元组做为字典的键值,比如坐标值作为字典的key
coordinates_map = {(100.23, 109.98): "北京", (200.98, 87.98): "上海"}
print(f"coordinates_map.items()={coordinates_map.items()}")
for k, v in coordinates_map.items():
    print(f"{k}这个经度和维度的地方是:{v}")


# 函数返回多个值，实际上返回的元组
def get_user_info():
    name = "alice"
    age = 30
    city = "苏州"
    return name, age, city


print(f"get_user_info函数返回多个值={get_user_info()},类型为:{type(get_user_info())}")

*params, city = get_user_info()
print(f"params= {params},city={city}")


# 元组的通过索引访问和切片
fruits = ("apple", "banana", "orange", "grape")

print(fruits[0])  # "apple" - 第一个元素
print(fruits[1])  # "banana" - 第二个元素
print(fruits[-1])  # "grape" - 最后一个元素
print(fruits[-2])  # "orange" - 倒数第二个元素
print(fruits[1:5])  #  利用索引进行切片

nums = (1, 2, 3, 4, 5)
one, *part, last = nums  # 混合加部分解包
print("one=", one, "part=", part, "last=", last)


# 具名元组


Student = namedtuple("StudentTuple", "no,name,age,score")


student_list = []
for i in range(20):
    id = str(i)
    student_list.append(
        Student(
            "A000" + str(i),
            f"Suzhou{id}",
            math.floor(random.random() * 100),
            math.floor(random.random() * 100),
        )
    )


print("=" * 50)
print(f"{'学号':<10}{'姓名':<10}{'年龄':<10}{'分数':<10}")
for stu in student_list:
    print(f"{stu.no:<10}{stu.name:<15}{stu.age:<11}{stu.score:<10}\n")
